import { HttpClient } from '@angular/common/http';
import { Inject, Injectable } from '@angular/core';
import { cacheConf } from '@conf/cache.conf';
import { sysConf } from '@conf/sys.conf';
import { ACLService } from '@delon/acl';
import { MenuService, SettingsService, TitleService, _HttpClient } from '@delon/theme';
import { AlainConfigService } from '@delon/util';
import { environment } from '@env/environment';
import { AmapService, EACacheService, EAUserService } from '@shared';
import { NzSafeAny } from 'ng-zorro-antd/core/types';
import { NzIconService } from 'ng-zorro-antd/icon';
import { NzImageService } from 'ng-zorro-antd/image';
import { NzUploadFile } from 'ng-zorro-antd/upload';
import { Observable, zip } from 'rxjs';
import { catchError, map } from 'rxjs/operators';

import { ICONS } from '../../../style-icons';
import { ICONS_AUTO } from '../../../style-icons-auto';
import { CoreService } from '../core.service';

/**
 * Used for application startup
 * Generally used to get the basic data of the application, like: Menu Data, User Data, etc.
 */
@Injectable()
export class StartupService {
  constructor(
    iconSrv: NzIconService,
    private menuService: MenuService,
    private settingService: SettingsService,
    private aclService: ACLService,
    private titleService: TitleService,
    private httpClient: _HttpClient,
    private userSrv: EAUserService,
    private amapService: AmapService,
    public cacheSrv: EACacheService,
    private coreSrv: CoreService,
    private nzImageService: NzImageService,
    private alainConfigService: AlainConfigService
  ) {
    iconSrv.addIcon(...ICONS_AUTO, ...ICONS);
    this.settingService.setLayout('fixSiderbar', true);
    // 全局修改sf图片预览方式
    alainConfigService.set('sf', {
      ui: {
        preview: (file: NzUploadFile) => {
          if (file.url) {
            this.nzImageService.preview([{ src: file.url }]);
          }
        }
      }
    });
  }

  // TODO: 退出登录时需要清理用户信息

  load(): Promise<void> {
    return new Promise(resolve => {
      this.amapService.getCurrentPosition().subscribe(res => {
        if (res.position) {
          this.coreSrv.position = { lat: res.position.lat, lng: res.position.lng };
        }
      });

      let data;
      if (this.coreSrv.loginStatus) {
        // 本地菜单
        // data = this.loadMockData();
        // 远程菜单
        data = this.loadRemoteData();
      } else {
        data = this.loadMockData();
      }

      data
        .pipe(
          catchError(res => {
            console.warn(`StartupService.load: Network request failed`, res);
            resolve();
            return [];
          })
        )
        .subscribe(
          ([appData, userData, menuData]) => this.initSystem(appData, userData, menuData),
          err => {
            console.log(err);
          },
          () => resolve()
        );
    });
  }

  /**
   * 系统初始化
   *
   * @param langData 翻译数据
   * @param appData App应用数据
   * @param userData 用户数据
   * @param menuData 菜单数据
   */
  private initSystem(appData: NzSafeAny, userData: NzSafeAny, menuData: NzSafeAny): void {
    // 应用信息：包括站点名、描述、年份
    this.settingService.setApp(appData);
    // 用户信息：包括姓名、头像、邮箱地址
    this.settingService.setUser(userData);
    this.cacheSrv.set(cacheConf.env, {
      appId: sysConf.appId,
      tenantId: userData?.tenantId || sysConf.tenantId,
      enterpriseId: userData?.enterpriseId || sysConf.enterpriseId
    });
    // ACL：设置权限为全量
    this.aclService.setFull(false);
    // 初始化菜单
    if (menuData) {
      this.menuService.add(menuData);
    }
    // 设置页面标题的后缀
    this.titleService.default = '';
    this.titleService.suffix = appData.name;
  }

  /**
   * @description 加载本地模拟数据
   * @returns 程序初始化数据
   */
  loadMockData(): Observable<[object, object, object]> {
    // 登录时调用远程数据， 非登录状态下调用Mock数据

    // App数据
    const appData = this.httpClient.get(`assets/mocks/app-data.json`).pipe(map((res: any) => res.app));

    // 用户数据
    const userData = this.httpClient.get('assets/mocks/user-data.json').pipe(map((res: any) => res.user));

    // 菜单数据
    const menuData = this.httpClient.get('assets/mocks/menu-data.json').pipe(map((res: any) => res.data.menu));

    return zip(appData, userData, menuData);
  }

  /**
   * @description 加载远程数据
   * @returns 程序初始化数据
   */
  loadRemoteData(): Observable<[object, object, object]> {
    // 登录时调用远程数据， 非登录状态下调用Mock数据

    // App数据
    const appData = this.httpClient.get(`assets/mocks/app-data.json`).pipe(map((res: any) => res.app));

    // 用户数据
    const userData = this.httpClient.post(this.userSrv.$api_get_user_by_token, {}).pipe(map((res: any) => res.data));

    // 菜单数据
    const menuData = this.httpClient
      .post(this.coreSrv.$api_get_current_user_menus, {
        appId: this.coreSrv.envSrv.getEnvironment().appId
      })
      .pipe(map((res: any) => res.data));
    // const menuData = this.httpClient.get('assets/mocks/menu-data.json').pipe(map((res: any) => res.data.menu));

    return zip(appData, userData, menuData);
  }

  // load(): Observable<void> {
  //   const defaultLang = this.i18n.defaultLang;
  //   return zip(this.i18n.loadLangData(defaultLang), this.httpClient.get('assets/tmp/app-data.json')).pipe(
  //     // 接收其他拦截器后产生的异常消息                                            
  //     catchError(res => {
  //       console.warn(`StartupService.load: Network request failed`, res);
  //       return [];
  //     }),
  //     map(([langData, appData]: [Record<string, string>, NzSafeAny]) => {
  //       // setting language data
  //       this.i18n.use(defaultLang, langData);

  //       // 应用信息：包括站点名、描述、年份
  //       this.settingService.setApp(appData.app);
  //       // 用户信息：包括姓名、头像、邮箱地址
  //       this.settingService.setUser(appData.user);
  //       // ACL：设置权限为全量
  //       this.aclService.setFull(true);
  //       // 初始化菜单
  //       this.menuService.add(appData.menu);
  //       // 设置页面标题的后缀
  //       this.titleService.default = '';
  //       this.titleService.suffix = appData.app.name;
  //     })
  //   );
  // }
}
